'use strict';

const Subscription = require('egg').Subscription,
  moment = require('moment'),
  redisKey = require('../utils/redis_key');

class PaymentTask extends Subscription {
  // 通过 schedule 属性来设置定时任务的执行间隔等配置
  static get schedule() {
    return {
      // interval: '0.1m', // 1 分钟间隔
      // type: 'all', // 指定所有的 worker 都需要执行
      cron: '0 */10 * * * *',
      type: 'all',
    };
  }

  // subscribe 是真正定时任务执行时被运行的函数
  async subscribe() {
    let payments = await this.ctx.app.model.Payment.find({
      pay_status: '30'
    })

    let apis = payments.map(item => {
      return this.ctx.app.pay.getPaymentInfo({
        orderId: item.ref_id,
        sysCode: item.pay_merchant_code,
        amount: item.amount,
        productCode: item.product_code,
        name: item.realname,
        idCardNo: item.id_card,
        bankCardNo: item.bank_card_no,
        bindMobile: item.phone_number
      })
    })

    let results = await Promise.all(apis)

    let doing = results.map((item, index) => {
      return async function() {
        if (item.code === 0) {
          if (item.data.payStatus === 10) { // 代付成功

            // 更新支付状态
            await this.ctx.app.model.Payment.update({ _id: payments[index]._id }, { pay_status: '10', update_time: new Date(), pay_time: new Date() })
            // 更新兑换状态 20 兑换成功
            await this.ctx.model.Exchange.update({ _id: item.orderId }, { status: '20', update_time: new Date(), grant_time: new Date() })
            // 查询奖品ids
            let exchange = await this.ctx.model.Exchange.findOne({ _id: item.orderId })
            // 更新奖品状态 20 发放成功
            await this.ctx.model.Prize.updateMany({ _id: { $in: exchange.prizes } }, { status: '20', update_time: new Date(), grant_time: new Date() })
            // 发放短信
            let product_code = payments[index].product_code.toLowerCase()

            let obj = {}

            // 产品code
            let pcode = ''
            if (product_code === 'hd_qyl') {
              pcode = 'qyl'
              obj.content = `【钱有路】用户您好，恭喜您获得奖励${payments[index].amount}元，已支付到您的银行卡，请注意查收；退订回复TD`
            } else if (product_code === 'hd_qsjs') {
              pcode = 'qsjs'
              obj.content = `【钱是金生】用户您好，恭喜您获得奖励${payments[index].amount}元，已支付到您的银行卡，请注意查收；退订回复TD`
            } else {
              pcode = 'ykqj'
              obj.content = `【一刻千金】用户您好，恭喜您获得奖励${payments[index].amount}元，已支付到您的银行卡，请注意查收；退订回复TD`
            }

            let signature_id = this.ctx.app.config.sms.options[pcode].signatureid
            let smsResult = await this.ctx.app.sms.send({
              "contentMap": {
                "award_name": payments[index].amount
              },
              "customerCode": 'NM',
              "extData": {},
              "mobile": payments[index].phone_number,
              "signatureId": signature_id,
              "templateId": this.ctx.app.config.sms.options[pcode].templates.cash
            })


            // 定义短信记录
            obj = Object.assign(obj, {
              campaign_id: payments[index].campaign_id,
              campaign_name: payments[index].campaign_name,
              product_code: pcode.toUpperCase(),
              ref_id: payments[index]._id,
              phone: payments[index].phone_number,
              signature_id: signature_id,
              template_id: this.ctx.app.config.sms.options[pcode].templates.cash,
              start_send_time: Date.now(),
              status: '10'
            })

            if (smsResult.code == '0000') { // 发送成功
              obj.status = '10',
                obj.sms_id = smsResult.body.mtSendRecordId
            } else { // 发送失败
              obj.status = '20'
            }
            let sms = new this.ctx.app.model.Sms(obj)
            await sms.save()

            return `订单号: ${item.orderId} 代付成功`

          } else if (item.data.payStatus === 20) { // 代付失败

            // 更新支付状态
            await this.ctx.app.model.Payment.update({ _id: payments[index]._id }, {
              pay_status: '20',
              pay_status_desc: item.data.errorMsg,
              update_time: new Date(),
              grant_time: new Date()
            })

            // 更新兑换状态 30 失败
            await this.ctx.model.Exchange.update({ _id: item.orderId }, { status: '30', update_time: new Date(), grant_time: new Date() })
            // 查询奖品ids
            let exchange = await this.ctx.model.Exchange.findOne({ _id: item.orderId })
            // 更新奖品状态 30 失败
            await this.ctx.model.Prize.updateMany({ _id: { $in: exchange.prizes } }, { status: '30', update_time: new Date(), grant_time: new Date() })

            // 释放金额
            let amount = payments[index].amount
            const redisKeyRateLimit = redisKey.rateLimit(payments[index].campaign_id);
            let dailyLimit = await this.ctx.app.redis.get(redisKeyRateLimit);
            await this.ctx.app.redis.set(redisKeyRateLimit, parseFloat(dailyLimit) + amount)
            let end = Math.floor(new Date(moment().add(1, 'days').format('YYYY-MM-DD 00:00:00')).getTime() / 1000)
            await this.ctx.app.redis.expireat(redisKeyRateLimit, end)

            return `订单号: ${item.orderId} 代付失败, 原因: ${item.data.errorMsg}.`

          } else { // 代付处理中
            return `订单号: ${item.orderId} 代付处理中`
          }
        } else { // 异常
          return `订单号: ${item.orderId} 查询异常, 原因：${item.msg}`
        }
      }.call(this)
    })

    let done = await Promise.all(doing)
    this.ctx.app.logger.info(done)
  }
}

module.exports = PaymentTask;
